<?php
/**
 * Created by 无所谓已
 * User: Administrator
 * Date: 2025-08-16
 * Time: 22:25
 */

namespace plugin\csauto\app\service;

use plugin\csauto\app\model\TorrentListModel;
use plugin\csauto\app\service\site\RssService;

class ToolService
{
    /**
     * @var string[]
     *              允许的Rss站点列表
     */
    private static $rssSite = [
        'hddolby',
        'cspt',
        'ubits',
        'audiences'
    ];
    /**
     * @var int
     */
    private static $addTorrentI = 2;

    public static function storeTorrent($rssList, $siteKey, $siteCookie)
    {
        $torrentI = 0;
        $data = array();
        foreach ($rssList as $item) {
            if ($torrentI >= self::$addTorrentI) continue;
            /*检查站点和信息*/
            if (ToolService::checkTorrentListStatus($item)) continue;
            if (!ToolService::checkTorrentSize($item['size'])) {
                addlog('storeTorrent', "当前种子大小：{$item['size']} GB,不满足RSS要求");
                continue;
            }
            if (!ToolService::checkTorrentWorkGroup(SiteWorkService::getSuffix($item['site_id']), $item['title'])) {
                addlog('storeTorrent', "当前种子后缀不匹配");
                continue;
            }
            $newData = ToolService::torrentView($item['link'], $siteCookie);
            $postData = ApiWorkService::setPostTorrentTaskDetails($item, $newData);
            $torrentI++;
            if (!is_array($postData)) {
                addlog('storeTorrentData', $postData);
                addlog('storeTorrent', '解析失败，终止当前条目');
                continue;
            }
            if (!isset($postData['torrent_parse'])) {
                addlog('storeTorrent', '返回解析失败，终止当前条目');
                continue;
            }
            if (RssService::addTorrent($item, $siteCookie, $postData['torrent_parse'])) {

            }
        }
    }

    public static function checkTorrentListStatus($item)
    {
        $torrentData = TorrentListModel::where('site_id', $item['site_id'])->where('torrent_id', $item['id'])->first();
        if ($torrentData) return true;
        return false;
    }

    public static function checkTorrentSize($size)
    {
        $sizeGb = convertToGB($size);
        if ($sizeGb > SystemService::getConfig(SystemService::TASK_RSS_MIN_SPACE) && $sizeGb <= SystemService::getConfig(SystemService::TASK_RSS_MAX_SPACE)) return true;
        return false;
    }

    public static function checkTorrentWorkGroup($list, $title)
    {
        if (preg_match('/[-@]([^@\-]+)$/', $title, $matches)) {
            $lastPart = trim($matches[1]);
            return in_array($lastPart, $list);
        }
        return false;
    }

    public static function torrentView($link, $siteCookie)
    {
        $heard = [];
        $heard[] = "Cookie: " . $siteCookie;
        echo "开始解析{$link}" . PHP_EOL;
        return ToolService::curlGetData($link, $heard);
    }

    /**
     * Created by 无所谓已
     * Date: 2025-08-16
     * Time: 23:38
     * curlGetData
     *
     * @param       $url
     * @param array $heard
     * @param false $isJson
     * @param null  $proxy
     * @return bool|mixed|string
     */
    public static function curlGetData($url, $heard = array(), $isJson = false, $proxy = null)
    {
        $curl = curl_init();

        $options = [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_HTTPHEADER => $heard,
        ];

        // 如果提供了代理配置，则设置代理
        if ($proxy && is_array($proxy)) {
            if (isset($proxy['host'])) {
                $options[CURLOPT_PROXY] = $proxy['host'];
            }
            if (isset($proxy['port'])) {
                $options[CURLOPT_PROXYPORT] = $proxy['port'];
            }
            if (isset($proxy['type'])) {
                $options[CURLOPT_PROXYTYPE] = $proxy['type']; // CURLPROXY_HTTP, CURLPROXY_SOCKS5 等
            }
            if (isset($proxy['username']) && isset($proxy['password'])) {
                $options[CURLOPT_PROXYUSERPWD] = $proxy['username'] . ':' . $proxy['password'];
            }
            if (isset($proxy['auth'])) {
                $options[CURLOPT_PROXYAUTH] = $proxy['auth']; // CURLAUTH_BASIC, CURLAUTH_NTLM 等
            }
        }

        curl_setopt_array($curl, $options);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);
        if ($err) {
            return false;
        } else {
            if ($isJson) {
                return json_decode($response, true);
            }
            return $response;
        }
    }

    /**
     * Created by 无所谓已
     * Date: 2025-08-16
     * Time: 23:38
     * CheckRssSite
     *
     * @param $siteKey
     * @return bool
     */
    public static function CheckRssSite($siteKey)
    {
        if (in_array($siteKey, ToolService::$rssSite)) return true;
        return false;
    }

    /**
     * Created by 无所谓已
     * Date: 2025-08-16
     * Time: 23:38
     * getXmlToArr
     *
     * @param $response
     * @param $siteKey
     * @return array|\SimpleXMLElement|string
     */
    public static function getXmlToArr($response, $siteKey, $siteId)
    {
        $xml = simplexml_load_string($response);
        switch ($siteKey) {
//            case 'hddolby':
//                $xml = ToolService::analysisXml($xml, $siteId);
//                break;
            default:
                $xml = ToolService::analysisXml($xml, $siteId);
                break;
        }

        return $xml;
    }

    public static function analysisXml($response, $siteId)
    {

        $list = array();
        foreach ($response->channel->item as $item) {
            $item->title = (string)$item->title;
            $item->comments = (string)$item->comments;
            $itemData = array(
//                'category' => $item->category,
                'id' => ToolService::getUrlId($item->link),
                'site_id' => $siteId,
                'link' => $item->link
//                'url' =>  $item->enclosure->attributes()->url[0]
            );
            foreach ($item->category->attributes() as $key => $value) {
                switch ($key) {
                    case 'domain':
                        $itemData['category'] = ToolService::getUrlId((string)$value, 'cat');
                        break;
                }
            }
            foreach ($item->enclosure->attributes() as $key => $value) {
                if ($key == 'type') continue;
//                if (is_array($value)) $value = $value[0];
                $itemData[$key] = (string)$value;
            }
            $analysisTitle = ToolService::analysisTitle($item->title);
            if ($analysisTitle) {
                $itemData['size'] = $analysisTitle['size'];
                $itemData['category_name'] = $analysisTitle['type'];
                $itemData['title'] = $analysisTitle['title'];
            }
            $list[] = $itemData;
        }
        echo "站点ID：{$siteId}，解析获得了：" . count($list) . "条数据" . PHP_EOL;
        return $list;
    }

    /**
     * Created by 无所谓已
     * Date: 2025-08-16
     * Time: 23:38
     * getUrlId
     * 从URL中提取ID
     *
     * @param        $url
     * @param string $key
     * @return int|mixed
     */
    public static function getUrlId($url, $key = 'id')
    {
        // 解析URL
        $parsedUrl = parse_url($url);
        // 解析查询字符串
        parse_str($parsedUrl['query'], $queryParams);

        return isset($queryParams[$key]) ? $queryParams[$key] : 0;
    }

    public static function analysisTitle($title)
    {
        // 使用正则表达式拆分成三部分
        $pattern = '/^(\[[^\]]+\])(.*?)(\[[^\]]+\])$/';
        preg_match($pattern, $title, $matches);
        // 如果要去掉方括号，可以使用以下方式：
        if (!empty($matches)) {
            $typeName = substr($matches[1], 1, -1);  // 去掉方括号: TV Series电视剧
            $titleName = trim($matches[2]);           // 中间部分保持不变
            $size = substr($matches[3], 1, -1);  // 去掉方括号: 95.14 GB
            return array(
                'type' => $typeName,
                'title' => $titleName,
                'size' => $size
            );
        }
        return false;
    }

    /**
     * Created by 无所谓已
     * Date: 2025-08-16
     * Time: 23:38
     * curlPostData
     *
     * @param       $url
     * @param array $data
     * @param array $headers
     * @param false $isJson
     * @return bool|mixed|string
     */
//    public static function curlPostData($url, $data = array(), $headers = array(), $isJson = false)
//    {
//        $curl = curl_init();
//
//        curl_setopt_array($curl, [
//            CURLOPT_URL => $url,
//            CURLOPT_RETURNTRANSFER => true,
//            CURLOPT_ENCODING => "",
//            CURLOPT_MAXREDIRS => 10,
//            CURLOPT_TIMEOUT => 30,
//            CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2, // 指定TLS版本
//            CURLOPT_SSL_VERIFYPEER => false, // 跳过SSL证书验证（仅用于测试）
//            CURLOPT_SSL_VERIFYHOST => false, // 跳过主机验证（仅用于测试）
//            // 或者使用更安全的方式：
//            // CURLOPT_CAINFO => '/path/to/cacert.pem', // 指定CA证书文件
//            CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
//            CURLOPT_CUSTOMREQUEST => "POST",
//            CURLOPT_POSTFIELDS => http_build_query($data),
//            CURLOPT_HTTPHEADER => $headers,
//        ]);
//
//        $response = curl_exec($curl);
//        $err = curl_error($curl);
//
//        curl_close($curl);
//        if ($err) {
//            return "error {$err}";
//        } else {
//            if ($isJson) {
//                return json_decode($response, true);
//            }
//            return $response;
//        }
//    }
    public static function curlPostData($url, $data = array(), $headers = array(), $isJson = false, $timeout = null, $connectTimeout = null)
    {
        $curl = curl_init();

        // 处理POST数据格式
        $postFields = $data;
        $contentType = 'application/x-www-form-urlencoded';

        // 检查数据大小，如果数据过大，使用JSON格式通过body提交
        $dataSize = 0;
        if (is_array($data)) {
            $dataSize = strlen(http_build_query($data));
            // 如果数据大小超过4KB，使用JSON格式
            if ($dataSize > 4096) {
                $postFields = json_encode($data, JSON_UNESCAPED_UNICODE);
                $contentType = 'application/json; charset=UTF-8';
            } else {
                $postFields = http_build_query($data);
            }
        } elseif (is_string($data)) {
            $dataSize = strlen($data);
            // 如果数据是字符串且长度很大，设置正确的Content-Type
            if ($dataSize > 4096) {
                $contentType = 'text/plain; charset=UTF-8';
            }
        }

        // 构建默认头部
        $defaultHeaders = [
            'Content-Type: ' . $contentType,
            'Content-Length: ' . strlen($postFields),
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
        ];

        // 合并自定义头部
        $allHeaders = array_merge($defaultHeaders, $headers);

        // 设置超时时间，如果未指定则使用默认值
        $timeoutValue = $timeout !== null ? $timeout : 300;
        $connectTimeoutValue = $connectTimeout !== null ? $connectTimeout : 30;

        curl_setopt_array($curl, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => $timeoutValue,
            CURLOPT_CONNECTTIMEOUT => $connectTimeoutValue,
            CURLOPT_SSLVERSION => CURL_SSLVERSION_DEFAULT,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => $postFields,
            CURLOPT_HTTPHEADER => $allHeaders,
            CURLOPT_VERBOSE => false,
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);
        $errno = curl_errno($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        curl_close($curl);

        if ($err) {
            return "cURL Error ({$errno}): {$err} | HTTP Code: {$httpCode}";
        } else {
            if ($isJson) {
                $jsonData = json_decode($response, true);
                if (is_array($jsonData)) return $jsonData;
            }
            return $response;
        }
    }

    /**
     * 专门用于大数据提交的POST方法
     * 强制使用JSON格式通过body提交，避免414错误
     *
     * @param string $url     请求URL
     * @param array  $data    要提交的数据
     * @param array  $headers 额外的请求头
     * @param bool   $isJson  是否期望JSON响应
     * @return bool|mixed|string
     */
    public static function curlPostDataLarge($url, $data = array(), $headers = array(), $isJson = false)
    {
        $curl = curl_init();

        // 强制使用JSON格式提交数据
        $postFields = json_encode($data, JSON_UNESCAPED_UNICODE);
        $contentType = 'application/json; charset=UTF-8';

        // 构建默认头部
        $defaultHeaders = [
            'Content-Type: ' . $contentType,
            'Content-Length: ' . strlen($postFields),
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
        ];

        // 合并自定义头部
        $allHeaders = array_merge($defaultHeaders, $headers);

        curl_setopt_array($curl, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 60, // 增加超时时间，因为数据可能较大
            CURLOPT_CONNECTTIMEOUT => 15,
            CURLOPT_SSLVERSION => CURL_SSLVERSION_DEFAULT,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => $postFields,
            CURLOPT_HTTPHEADER => $allHeaders,
            CURLOPT_VERBOSE => false,
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);
        $errno = curl_errno($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        curl_close($curl);

        if ($err) {
            return "cURL Error ({$errno}): {$err} | HTTP Code: {$httpCode}";
        } else {
            if ($isJson) {
                $jsonData = json_decode($response, true);
                if (is_array($jsonData)) {
                    return $jsonData;
                } else {
                    addlog('curlPostDataLarge', $response, 'error');
                }
            }
            return $response;
        }
    }

    public static function uploadTorrentToNexusPHP($url, $torrentFilePath, $data = array(), $cookies = array())
    {
        // 检查种子文件是否存在
        if (!file_exists($torrentFilePath)) {
            throw new \Exception("种子文件不存在: " . $torrentFilePath);
        }

        // 创建边界字符串
        $boundary = '----WebKitFormBoundary' . uniqid();

        // 构建请求头
        $headers = [
            'Content-Type: multipart/form-data; boundary=' . $boundary,
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
        ];
        foreach ($cookies as $value) {
            $headers[] = $value;
        }
        // 构建multipart body
        $body = '';

        // 添加表单数据字段
        foreach ($data as $key => $value) {
            // 处理数组类型的字段
            if (is_array($value)) {
                foreach ($value as $subKey => $subValue) {
                    $fieldKey = $key . '[' . $subKey . ']';
                    $body .= "--{$boundary}\r\n";
                    $body .= "Content-Disposition: form-data; name=\"{$fieldKey}\"\r\n\r\n";
                    $body .= "{$subValue}\r\n";
                }
            } else {
                $body .= "--{$boundary}\r\n";
                $body .= "Content-Disposition: form-data; name=\"{$key}\"\r\n\r\n";
                $body .= "{$value}\r\n";
            }
        }

        // 添加种子文件字段
        $fileName = basename($torrentFilePath);
        $fileContent = file_get_contents($torrentFilePath);

        $body .= "--{$boundary}\r\n";
        $body .= "Content-Disposition: form-data; name=\"file\"; filename=\"{$fileName}\"\r\n";
        $body .= "Content-Type: application/x-bittorrent\r\n\r\n";
        $body .= "{$fileContent}\r\n";
        $body .= "--{$boundary}--\r\n";

        // 使用curl发送请求
        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => $body,
            CURLOPT_HTTPHEADER => $headers,
//            CURLOPT_FOLLOWLOCATION => false, // 不自动跟随重定向，以便捕获302信息
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $redirectUrl = curl_getinfo($curl, CURLINFO_REDIRECT_URL);


        curl_close($curl);

        if ($err) {
            return ['error' => $err];
        } else {
            $result = [
                'http_code' => $httpCode,
                'response' => $response,
                'redirect_url' => $redirectUrl,
//                'headers' => $headers
            ];
            return $result;
        }
    }


    public static function convert($html)
    {
        // 先保存现有的<a>标签为BBCode格式
        $links = [];
        $html = preg_replace_callback('/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/i', function ($matches) use (&$links) {
            $placeholder = '___LINK_PLACEHOLDER_' . count($links) . '___';
            $links[$placeholder] = '[url=' . $matches[1] . ']' . $matches[2] . '[/url]';
            return $placeholder;
        }, $html);

        // 保存图片标签为BBCode格式
        $images = [];
        $html = preg_replace_callback('/<img[^>]*src="([^"]*)"[^>]*>/i', function ($matches) use (&$images) {
            $placeholder = '___IMG_PLACEHOLDER_' . count($images) . '___';
            $images[$placeholder] = '[img]' . $matches[1] . '[/img]';
            return $placeholder;
        }, $html);

        // 处理嵌套的span和font标签 - 重复处理直到没有更多匹配
        do {
            $count = 0;

            // 转换<span style="color: xxx">为[color=xxx] (支持嵌套)
            $html = preg_replace_callback(
                '/<span[^>]*style="[^"]*color:\s*([^;"]+)[^"]*"[^>]*>((?:(?!<\/span>).)*)<\/span>/is',
                function ($matches) {
                    $color = trim($matches[1]);
                    $color = preg_replace('/\s+/', '', $color);
                    return '[color=' . $color . ']' . $matches[2] . '[/color]';
                },
                $html,
                -1,
                $count1
            );
            $count += $count1;

            // 转换<font color="xxx">为[color=xxx] (支持嵌套)
            $html = preg_replace_callback(
                '/<font[^>]*color="([^"]*)"[^>]*>((?:(?!<\/font>).)*)<\/font>/is',
                function ($matches) {
                    return '[color=' . $matches[1] . ']' . $matches[2] . '[/color]';
                },
                $html,
                -1,
                $count2
            );
            $count += $count2;

            // 转换<font size="xxx">为[size=xxx] (支持嵌套)
            $html = preg_replace_callback(
                '/<font[^>]*size="([^"]*)"[^>]*>((?:(?!<\/font>).)*)<\/font>/is',
                function ($matches) {
                    return '[size=' . $matches[1] . ']' . $matches[2] . '[/size]';
                },
                $html,
                -1,
                $count3
            );
            $count += $count3;

        } while ($count > 0);

        // 处理<b>标签
        $html = preg_replace('/<b>(.*?)<\/b>/is', '[b]$1[/b]', $html);

        // 为文本中的URL添加BBCode链接（排除已有链接）
        $html = preg_replace_callback('/(?<!url=)(https?:\/\/[^\s\[\]]+)/i', function ($matches) {
            return '[url=' . $matches[1] . ']' . $matches[1] . '[/url]';
        }, $html);

        // 转换其他HTML标签为BBCode
        $bbcode = $html;

        // 转换<fieldset>为[code]标签
        $bbcode = preg_replace('/<fieldset>(.*?)<\/fieldset>/is', '[quote]$1[/quote]', $bbcode);

        // 转换<legend>为粗体
        $bbcode = preg_replace('/<legend>(.*?)<\/legend>/i', '[b]$1[/b]', $bbcode);

        // 转换&nbsp;为空格
        $bbcode = str_replace('&nbsp;', ' ', $bbcode);

        // 移除其他HTML标签
        $bbcode = strip_tags($bbcode);

        // 恢复图片BBCode
        foreach ($images as $placeholder => $image) {
            $bbcode = str_replace($placeholder, $image, $bbcode);
        }

        // 恢复链接BBCode
        foreach ($links as $placeholder => $link) {
            $bbcode = str_replace($placeholder, $link, $bbcode);
        }

        // 清理多余的空白字符
        $bbcode = preg_replace('/\n{3,}/', "\n\n", $bbcode);

        return $bbcode;
    }


    /**
     * 数组转换字符串（以逗号隔开）
     *
     * @param
     * @return
     */
    public static function arrayToString($array, $t = ',', $s = '')
    {
        if (!is_array($array)) {
            $data_arr[] = $array;
        } else {
            $data_arr = $array;
        }
        $data_arr = array_filter($data_arr); //数组去空
        $data_arr = array_unique($data_arr); //数组去重
        $data_arr = array_merge($data_arr);
        $string = $data_arr ? $s . implode($t . $s, $data_arr) : '';
        return $string ?: '';
    }

    /**
     * 字符串转换数组（以逗号隔开）
     *
     * @param
     * @return
     */
    public static function stringToArray($string, $t = ',')
    {
        if (is_array($string)) {
            $data_arr = array_unique(array_filter($string));
        } else {
            $data_arr = $string ? array_unique(array_filter(explode($t, $string))) : [];
        }
        $data_arr = $data_arr ? array_merge($data_arr) : [];
        return $data_arr ?: [];
    }
}